#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <LittleFS.h>
#include <WiFiManager.h>
#include <ArduinoJson.h>
#include "conf.h"
#include "Hass-Mqtt.h"
#include <OneButton.h>

// include MDNS
#ifdef ESP8266
#include <ESP8266mDNS.h>
#elif defined(ESP32)
#include <ESPmDNS.h>
#endif

extern bool callwebportal;

WiFiManager wm;
WiFiManagerParameter custom_mqtt_server("mqtt_server", "mqtt_server", "", 40);
WiFiManagerParameter custom_mqtt_port("mqtt_port", "mqtt_port", "", 6);
WiFiManagerParameter custom_mqtt_userid("mqtt_userid", "mqtt_userid", "", 30);
WiFiManagerParameter custom_mqtt_pswd("mqtt_pswd", "mqtt_pswd", "", 30);

unsigned int timeout = 120; // seconds to run for
unsigned int startTime = millis();
bool portalRunning = false;
bool startAP = false; // start AP and webserver if true, else start only webserver
bool shouldSaveConfig = false;

void configPortalTimeoutCallback(){
  delay(1000);
  wm.autoConnect();
}

void saveParamsCallback()
{
  shouldSaveConfig = true;
}

void wm_init(){
    WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
    // pinMode(TRIGGER_PIN, INPUT_PULLUP);

    /* read configuration from FS json */
    Serial.println("mounting FS...");
    if (LittleFS.begin())
    {
        Serial.println("mounted file system");
        if (LittleFS.exists("/config.json"))
        {
            // file exists, reading and loading
            // Serial.println("reading config file");
            File configFile = LittleFS.open("/config.json", "r");
            if (configFile)
            {
                // Serial.println("opened config file");
                size_t size = configFile.size();
                // Allocate a buffer to store contents of the file.
                std::unique_ptr<char[]> buf(new char[size]);
                configFile.readBytes(buf.get(), size);
                JsonDocument json;
                deserializeJson(json, buf.get());
                serializeJson(json, Serial);

                custom_mqtt_server.setValue(json["mqtt_server"], 30);
                custom_mqtt_port.setValue(json["mqtt_port"], 6);
                custom_mqtt_userid.setValue(json["mqtt_userid"], 30);
                custom_mqtt_pswd.setValue(json["mqtt_pswd"], 30);

                configFile.close();
            }
        }
    }
    else
    {
        Serial.println("failed to mount FS");
    }

    /* add mqtt config lable to web */
    wm.addParameter(&custom_mqtt_server);
    wm.addParameter(&custom_mqtt_port);
    wm.addParameter(&custom_mqtt_userid);
    wm.addParameter(&custom_mqtt_pswd);
    
    /* set call back function */
    wm.setSaveParamsCallback(saveParamsCallback);
    wm.setConfigPortalTimeoutCallback(configPortalTimeoutCallback);
    wm.setHostname("MCH_ESP");
    wm.setConfigPortalBlocking(false);
    wm.setConfigPortalTimeout(90);
    wm.autoConnect();
    Serial.println("\n Starting");
}

/* this function should put in loop */
void doWiFiManager()
{
  wm.process(); // do processing

  // is auto timeout portal running
  if (portalRunning)
  {
    // check for timeout
    if ((millis() - startTime) > (timeout * 1000))
    {
      Serial.println("portaltimeout");
      digitalWrite(STATUS_LED, HIGH); //turn off the status led
      portalRunning = false;
      if (startAP)
      {
        wm.stopConfigPortal();
      }
      else
      {
        wm.stopWebPortal();
      }
    }
  }

  // is configuration portal requested?
  if (callwebportal && (!portalRunning))
  {
    if (startAP)
    {
      Serial.println("Button Pressed, Starting Config Portal");
      wm.setConfigPortalBlocking(false);
      wm.startConfigPortal();
    }
    else
    {
      Serial.println("Button Pressed call for Web Portal");
      if(STATUS_LED>0)digitalWrite(STATUS_LED, LOW);  // turn on the status led, means the web portal is working
      wm.startWebPortal();
    }
    portalRunning = true;
    callwebportal = false;
    startTime = millis();
  }

  /* is mqtt config should update?*/
  if (shouldSaveConfig)
  {
    Serial.println("saving config");
    JsonDocument json;
    json["mqtt_server"] = custom_mqtt_server.getValue();
    json["mqtt_port"] = custom_mqtt_port.getValue();
    json["mqtt_userid"] = custom_mqtt_userid.getValue();
    json["mqtt_pswd"] = custom_mqtt_pswd.getValue();

    File configFile = LittleFS.open("/config.json", "w");
    if (!configFile)
    {
      Serial.println("failed to open config file for writing");
    }
    serializeJson(json, Serial);
    serializeJson(json, configFile);
    configFile.close();
    shouldSaveConfig = false;
  }
}
